﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Taobao.Top.Api.Request;
using Taobao.Top.Api.Domain;
using Model = TaobaoDistrSales.Model;
using System.Threading;

namespace TaobaoDistrSales.Common
{
    public class TaobaoFeiXiaoProcessor:TaobaoProcessor
    {
        #region Ctors

        public TaobaoFeiXiaoProcessor(short shopid)
            : base(shopid)
        {
        }

        public TaobaoFeiXiaoProcessor(short shopid, IOutputWriter writer)
            : base(shopid, writer)
        { 
        }

        #endregion

        #region Switch Shop

        public Func<Model.Shop,short> SwitchShop;

        #endregion

        #region Override Methods

        protected override void DoExcuteJob()
        {
            string msg = "starting";
            try
            {
                OutputWriter.WriteLine("");
                ExcuteUpdateStatus("程序开始执行");                 

                SendDeliveries();

                UpdateRefunds();

                UpdateNotFinishedTradeInfosFromTAOBAO();

                UpdateTraders();

                UpdatePurchaseOrders();

                UpdatePurchaseSubOrders();

                SaveTradesDeliveries();

                SavePurchaseOrderDeliveries();

                SendDeliveries();

                ExcuteUpdateStatus("程序执行完毕"); 
                OutputWriter.WriteLine("API执行完毕！", OutputFormatType.Title);
                OnProcessCompleted(EventArgs.Empty);
                msg = "completed";
            }
            catch (Exception e)
            {
                HandleException("程序运行中出错。",e);
            }
            finally
            {
                try
                {
                    if (ResourceManager.Current.OptionsConfig.clearoutput)
                    {
                        Thread.Sleep(ThreadSleepTick);
                        OutputWriter.Clear();
                        Thread.Sleep(ThreadSleepTick);
                    }

                    if (msg == "completed")
                    {

                        var interval = ResourceManager.Current.OptionsConfig.processinterval * 60;
                        var hours = ResourceManager.Current.OptionsConfig.processinterval / 60;
                        var minutes = ResourceManager.Current.OptionsConfig.processinterval % 60;
                        var seconds = 0;
                        while (interval-- > 0 && msg == "completed")
                        {
                            hours = interval / (60 * 60);
                            minutes = (interval % (60 * 60)) / 60;
                            seconds = interval % 60;
                            TimeSpan timeSpan = new TimeSpan(hours, minutes, seconds);
                            ExcuteUpdateStatus("程序将在:" + timeSpan.ToString() + " 后重新自动执行。");
                            Thread.Sleep(1000);
                        }
                        if (SwitchShop != null && msg == "completed")
                        {
                            try
                            {
                                InitializeEntities();
                                var sp = SwitchShop(Shop);
                                var newShop = (from s in Entities.Shop
                                               where s.ShopId == sp
                                               select s).FirstOrDefault();
                                if (newShop != null)
                                    ShopID = newShop.ShopId;
                                DisposeEntities();
                            }
                            catch { }
                        }
                    }
                }
                catch(Exception error) {
                    HandleException("程序重新运行中出错。", error);
                    ExcuteUpdateStatus("程序将重新自动执行。");
                }
                finally
                {
                    DisposeEntities();
                    DoExcuteJob();
                }
            }
        }
       
        #endregion

        #region Update From Taobao

        /// <summary>
        /// Update the Distributors From TAOBAO to DataBase
        /// </summary>
        /// <param name="nicks"></param>
        protected void UpdateDistributors(string nicks)
        {
            ExcuteUpdateStatus("开始更新分销商信息");

            try
            {
                OutputWriter.WriteLine("开始更新分销商信息！", OutputFormatType.Title);
                FenXiaoGetDistributorsRequest request = new FenXiaoGetDistributorsRequest();
                request.Nicks = nicks;
                var firstRefunds = Client.FenXiaoGetDistributors(request);
                
            }
            catch (Exception e)
            {
                HandleException("更新分销商信息失败。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新分销商信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }
         
        /// <summary>
        /// Update the Refund Information from TAOBAO to Database
        /// </summary>
        protected void UpdateRefunds()
        {
            long total = 0;
            long success = 0;
            string title = "分销采购单的退款信息";
            ExcuteUpdateStatus("正在更新分销采购单的退款信息");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新分销的退款采购单！", OutputFormatType.Title);

                RefundsReceiveGetRequest request = new RefundsReceiveGetRequest();
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Fields = "refund_id, tid, title, buyer_nick, seller_nick, total_fee, status, created, refund_fee, oid, good_status, company_name, sid, payment, reason, desc, has_good_return, modified, order_status ";
                request.Type = "fenxiao";
                PageList<Refund> firstRefunds = Client.RefundsReceiveGet(request);

                LogstatisticsStart(title, total=firstRefunds.TotalResults);

                success = ProcessPageList<Refund>("分销采购单的退款信息", request.PageSize.Value, firstRefunds,
                    (pageNo) => 
                    {
                        request.PageNo = pageNo;
                        return Client.RefundsReceiveGet(request);
                    },
                    SaveRefund);              

            } 
            catch (Exception e)
            {
                HandleException("更新分销采购单的退款信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title,total,success);
                DisposeEntities();
            }
        }

        protected void UpdatePurchaseOrders()
        {
            long total = 0, success = 0;
            string title = "交易的分销采购单";
            ExcuteUpdateStatus("开始更新交易的分销采购单");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新所有未发货交易的分销采购单...", OutputFormatType.Title);
                List<Model.Trade> dTradeList = (from t in Entities.Trade
                                                where t.Shop.ShopId == ShopID
                                                && t.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                                select t).ToList();
                
                LogstatisticsStart(title,total=dTradeList.Count);
                foreach (Model.Trade trade in dTradeList)
                {
                    if (UpdatePurchaseOrders(trade))
                        success++;
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
                DisposeEntities();
            }
        }

        /// <summary>
        /// Update the Purchase Orders From TAOBAO to Database
        /// </summary>
        protected bool UpdatePurchaseOrders(Model.Trade dTrade)
        {
            int total = 0;
            int success = 0;
            try
            {
                //OutputWriter.WriteLine("开始更新交易:"+dTrade.tid+"的分销采购单。", OutputFormatType.Title);
                
                FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                request.PurchaseOrderID = dTrade.tid;
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;// "WAIT_SELLER_SEND_GOODS";
                PageList<PurchaseOrder> firstPurchaseOrderList = Client.FenXiaoGetOrders(request);
                if (firstPurchaseOrderList.Content.Count > 0)
                {
                    if (SavePurchaseOrder(firstPurchaseOrderList.Content[0],true))
                        success++;
                }     

            }
            catch (Exception e)
            {
                HandleException("更新交易:"+dTrade.tid+"的分销采购单异常。", e);
            }
            finally
            { 
            }
            return success > 0;
        }

        /// <summary>
        /// Update the Purchase Sub Orders from TAOBAO to Database
        /// </summary>
        protected void UpdatePurchaseSubOrders()
        {
            long total = 0, success = 0,subTotal =0;
            string title = "分销采购单的子采购单信息";
            ExcuteUpdateStatus("开始更新分销采购单的子采购单信息");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新分销采购单的子采购单...", OutputFormatType.Title);

                var allPurchaseOrders = (from o in Entities.PurchaseOrder
                                        where o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                        && o.Shop.ShopId==ShopID
                                         select o).ToList();

                total = allPurchaseOrders.Count;
                OutputWriter.WriteLine("总共有：" + allPurchaseOrders.Count + "分销采购单的子采购单需要更新。", OutputFormatType.Title);

                allPurchaseOrders.ForEach(o =>
                    {
                        int t = 0, s = 0;
                        try
                        {
                            FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                            request.PageSize = 100;
                            request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;// "WAIT_SELLER_SEND_GOODS";
                            request.PurchaseOrderID = o.id;
                            PageList<PurchaseOrder> orders = Client.FenXiaoGetOrders(request);
                          
                            if (orders.Content.Count > 0)
                            {
                                var torder = orders.Content[0];
                                var subOrders = torder.SubPurchaseOrders;
                                t += subOrders.Count;

                                if (subOrders != null && subOrders.Count() > 0)
                                {
                                    foreach (var tsubOrder in subOrders)
                                    {
                                        try
                                        {
                                            if (SaveSubPurchaseOrder(o, tsubOrder,true))
                                                s++;
                                        }
                                        catch (Exception e)
                                        {
                                            HandleException("更新分销采购单:" + o.id + "的子采购单:" + tsubOrder.ID + "失败.", e);
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            HandleException("更新分销采购单:" + o.id + "的子采购单失败.", e);
                        }
                        OutputWriter.WriteLine("分销采购单:" + o.id + " 一共有:" + t + "条子采购单，成功更新了：" + s + "条。", OutputFormatType.Title);
                       
                        subTotal += t;
                        success += s;
                    });
                
            }
            catch (Exception e)
            {
                HandleException("更新分销采购单的子采购单异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("一共有："+total+"条未发货的分销采购单，其中包含了："+subTotal+" 条子采购单，成功更新了："+success+"条子采购单。", OutputFormatType.Title);
                OutputWriter.WriteLine("结束更新分销采购单的子采购单！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
                DisposeEntities();
            }
        }     
        
        protected void UpdateTraders()
        {
            long total = 0;
            long success = 0;
            string title = "分销交易信息";
            ExcuteUpdateStatus("正在更新分销交易信息");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新分销交易信息...", OutputFormatType.Title);

                TradesSoldGetRequest request = new TradesSoldGetRequest();
                request.Type = Constants.TradeType_FenXiao;
                request.Status = Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS;
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                request.Fields = "title, type, created, sid, tid,end_time, received_payment, alipay_no, iid, num, price, shipping_type";
                request.StartCreated = new DateTime?(DateTime.Parse("1990.01.01"));
                request.EndCreated = new DateTime?(DateTime.Now);
                PageList<Trade> firstTradeList = Client.TradesSoldGet(request);

                LogstatisticsStart(title, total = firstTradeList.TotalResults);

                success = ProcessPageList<Trade>("分销交易信息", request.PageSize.Value,
                    firstTradeList,
                    (pageNo) => {
                        request.PageNo = pageNo;
                        return Client.TradesSoldGet(request);
                    },
                    SaveFullTrade
                    );
                
            }
            catch (Exception e)
            {
                HandleException("更新分销交易信息异常。", e);
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
                DisposeEntities();
            }
        }

        #endregion

        #region Save to DataBase

        protected void SaveTradesDeliveries()
        {
            long total = 0, success = 0;
            string title = "";
            ExcuteUpdateStatus("开始更新需要发货的分销交易的物流信息...");
            try
            {
                InitializeEntities();
                List<Model.Trade> allUnsentTrades = (from t in Entities.Trade
                                                     where t.Shop.ShopId == ShopID
                                                      && t.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                                     select t).ToList();
                total = allUnsentTrades.Count;
                OutputWriter.WriteLine("开始对分销交易做发货处理...", OutputFormatType.Title);

                foreach (Model.Trade trade in allUnsentTrades)
                {
                    try
                    {
                        Model.FenXiaoDeliveryCache deliveryCache = (from d in Entities.FenXiaoDeliveryCache
                                                                    where d.Trade != null
                                                                    && d.Trade.tid == trade.tid
                                                                    && d.Shop != null
                                                                    && d.Shop.ShopId == ShopID
                                                                    select d).FirstOrDefault();
                        bool addRecord = deliveryCache == null;
                        if (addRecord)
                        {
                            deliveryCache = new Model.FenXiaoDeliveryCache();
                        }
                        deliveryCache.Shop = Shop;
                        try
                        {
                            //Confirm the trade is waiting seller send goods.
                            TradeFullinfoGetRequest tradeRequest = new TradeFullinfoGetRequest();
                            tradeRequest.Tid = trade.tid;
                            tradeRequest.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                            Trade tTrade = Client.TradeFullinfoGet(tradeRequest);
                            if (tTrade.Status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                            {
                                // Has been Sent In other place.
                                SaveTrade(tTrade, false);
                                trade.status = tTrade.Status;

                                var allPOrders = (from o in Entities.PurchaseOrder
                                                  where o.Shop.ShopId == ShopID
                                                  && o.id == trade.tid
                                                  select o).ToList();
                                allPOrders.ForEach(o =>
                                {
                                    o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    o.SubPurchaseOrder.Load();
                                    foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                    {
                                        subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    }
                                });
                                Entities.SaveChanges();
                            }
                        }
                        catch (Exception te)
                        { }

                        deliveryCache.Trade = (from t in Entities.Trade
                                               where t.tid == trade.tid
                                               && t.Shop.ShopId == ShopID
                                               select t).FirstOrDefault();
                        if (deliveryCache.Trade != null && deliveryCache.Trade.status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                        {
                            deliveryCache.IsSucess = true;
                            deliveryCache.Status = Constants.Delivery_Completed;
                        }

                        string deliveryMsg = String.Empty;
                        if (trade.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                        {
                            deliveryCache.IsSucess = false;
                            deliveryCache.Status = Constants.Delivery_Waiting;
                            deliveryMsg = "等待发货";
                        }
                        else if (trade.status == Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS
                            || trade.status == Constants.PurchaseOrder_TRADE_FINISHED)
                        {
                            deliveryCache.IsSucess = true;
                            deliveryCache.Status = Constants.Delivery_Completed;
                            deliveryMsg = "已在其他地方完成发货";
                        }
                        else
                        {
                            deliveryCache.IsSucess = false;
                            deliveryCache.Status = Constants.Delivery_UnKnown;
                            deliveryMsg = "未知";
                        }


                        StringBuilder message = new StringBuilder();
                        if (addRecord)
                        {
                            Entities.AddToFenXiaoDeliveryCache(deliveryCache);
                            Entities.SaveChanges();
                            message.AppendFormat("添加分销交易:{0}的物流信息,{1}.", trade.tid, deliveryMsg);
                        }
                        else
                        {
                            Entities.SaveChanges();
                            message.AppendFormat("更新分销交易:{0}的物流信息,{1}.", trade.tid, deliveryMsg);
                        }

                        OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    }
                    catch (Exception error)
                    {
                        HandleException("更新将要发货的分销交易记录：" + trade.tid + "失败！", error);
                    }
                }
            }
            catch (Exception e)
            {
                HandleException("更新将要发货的分销交易记录异常！", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新需要发货的分销交易的物流信息", OutputFormatType.Title);
                OutputWriter.WriteLine("");
                DisposeEntities();
            }
        }

        /// <summary>
        /// Check all the purchase order's status in the database, to collect the needed delivery ones.
        /// </summary>
        protected void SavePurchaseOrderDeliveries()
        {
            ExcuteUpdateStatus("正在更新需要发货的采购单信息");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新需要发货的分销采购单的物流信息...", OutputFormatType.Title);

                var allOrders = (from o in Entities.PurchaseOrder
                                 where o.Shop.ShopId == ShopID
                                 && o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                 select o).ToList();
                allOrders.ForEach(o =>
                {

                    try
                    {
                        var delivery = (from d in Entities.FenXiaoDeliveryCache
                                        where d.Trade != null && d.Trade.tid == o.id
                                        && d.Shop.ShopId == ShopID
                                        select d).FirstOrDefault();

                        var addRecord = delivery == null;
                        if (addRecord)
                        {
                            delivery = new Model.FenXiaoDeliveryCache();
                        }

                        #region Set Trade
                        try
                        {
                            TradeFullinfoGetRequest tradeRequest = new TradeFullinfoGetRequest();
                            tradeRequest.Tid = o.id;
                            tradeRequest.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                            Trade tTrade = Client.TradeFullinfoGet(tradeRequest);

                            if (SaveTrade(tTrade, false))
                            {
                                delivery.Trade = (from t in Entities.Trade
                                                  where t.tid == o.id
                                                  && t.Shop.ShopId == ShopID
                                                  select t).FirstOrDefault();
                            }
                        }
                        catch (Exception te)
                        {
                        }

                        //Confirm the trade is from the TAOBAO, and If it's status is not “wait_seller_send_goods”,
                        //We should not add the trade to the unsent delivery table, and shou change the PurchaseOrder's status
                        if (delivery.Trade != null && delivery.Trade.status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                        {
                            o.status = delivery.Trade.status;
                            delivery.IsSucess = true;
                            delivery.Status = Constants.Delivery_Completed;
                        }
                        #endregion

                        string deliveryMsg = String.Empty;
                        if (o.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS)
                        {
                            delivery.IsSucess = false;
                            delivery.Shop = Shop;
                            delivery.Status = Constants.Delivery_Waiting;
                            deliveryMsg = "等待发货";
                        }
                        else if (o.status == Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS
                            || o.status == Constants.PurchaseOrder_TRADE_FINISHED)
                        {
                            deliveryMsg = "已在其他地方完成发货";
                        }
                        else
                        {
                            delivery.Status = Constants.Delivery_UnKnown;
                            deliveryMsg = "未知";
                        }

                        StringBuilder message = new StringBuilder();
                        if (addRecord)
                        {
                            Entities.AddToFenXiaoDeliveryCache(delivery);
                            Entities.SaveChanges();
                            message.AppendFormat("添加分销采购单:{0}的物流信息,{1}.", o.id, deliveryMsg);
                        }
                        else
                        {
                            Entities.SaveChanges();
                            message.AppendFormat("更新分销采购单:{0}的物流信息,{1}.", o.id, deliveryMsg);
                        }

                        OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                    }
                    catch (Exception ep)
                    {
                        HandleException("更新分销采购单:" + o.id + "的物流信息失败.", ep);
                    }
                });
            }
            catch (Exception e)
            {
                HandleException("更新需要发货的分销采购单的物流信息异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新需要发货的分销采购单的物流信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
                DisposeEntities();
            }
        }

        /// <summary>
        /// Send the purchase order which need the seller to send product.
        /// </summary>
        protected void SendDeliveries()
        {
            ExcuteUpdateStatus("正在发货...");
            int totalCount = 0;
            int succeedCount = 0;
            try
            {
                InitializeEntities();

                OutputWriter.WriteLine("开始处理采购单发货...", OutputFormatType.Title);

                var allOrderDeliveries = (from d in Entities.FenXiaoDelivery
                                          where (d.Status == Constants.Delivery_Waiting || d.Status == Constants.Delivery_Failed)
                                          && d.Shop.ShopId == ShopID
                                          && d.Trade != null 
                                          && d.Trade.status == Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                          && ((d.OrderType == Constants.OrderType_Delivery_Needed && !String.IsNullOrEmpty(d.OutSID))
                                                || (d.OrderType == Constants.OrderType_Virtual_Goods))
                                          select d).ToList();

                totalCount = allOrderDeliveries.Count;
                LogstatisticsStart("采购单发货", totalCount);

                allOrderDeliveries.ForEach(d =>
                {
                    Model.FenXiaoDeliveryCache dCache = null;
                    try
                    {
                        dCache = (from dc in Entities.FenXiaoDeliveryCache
                                                             where dc.Trade != null && dc.Shop.ShopId == ShopID
                                                             && dc.Trade.tid == d.Trade.tid
                                                             select dc).FirstOrDefault();
                        bool needAddCache = dCache == null;

                        try
                        {
                            if (needAddCache)
                            {
                                dCache = new Model.FenXiaoDeliveryCache();
                            }
                            dCache.CompanyCode = d.CompanyCode;
                            dCache.IsSucess = d.IsSucess;
                            dCache.Memo = d.Memo;
                            dCache.OrderType = d.OrderType;
                            dCache.OutSID = d.OutSID;
                            dCache.Shop = d.Shop;
                            dCache.Status = d.Status;
                            dCache.Trade = d.Trade;
                            if (needAddCache)
                            {
                                Entities.AddToFenXiaoDeliveryCache(dCache);
                            }
                            Entities.SaveChanges();
                        }
                        catch { }

                        bool hasSent = false;
                        bool needSend = false;
                        try
                        {
                            dCache.TradeReference.Load();
                            TradeGetRequest tradeGetRequest = new TradeGetRequest();
                            tradeGetRequest.Tid = dCache.Trade.tid;
                            tradeGetRequest.Fields = "tid, status, payment,consign_time";
                            Trade realTrade = Client.TradeGet(tradeGetRequest);
                            hasSent = (realTrade.Status != Constants.PurchaseOrder_WAIT_SELLER_SEND_GOODS
                                         && !String.IsNullOrEmpty(realTrade.ConsignTime)); 

                            #region Has been Sent in other place
                            if (hasSent)
                            {
                                OutputWriter.WriteLine("采购单:"+realTrade.Tid+" 以在其他地方发货。", OutputFormatType.Success);
                                dCache.Status = Constants.Delivery_Completed;
                                dCache.IsSucess = true;
                                succeedCount++;
                                Entities.SaveChanges();
                                //Update Trade && PurchaseOrder 
                                try
                                {
                                    SaveTrade(realTrade,false);

                                    dCache.TradeReference.Load();
                                    dCache.Trade.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    
                                    List<Model.PurchaseOrder> purchaseOrders = (from o in Entities.PurchaseOrder
                                                                                where o.Trade.tid == dCache.Trade.tid
                                                                                && o.Shop.ShopId == ShopID
                                                                                select o).ToList();
                                    purchaseOrders.ForEach(o =>
                                    {
                                        o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                        o.SubPurchaseOrder.Load();
                                        foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                        {
                                            subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                        }
                                    });
                                    Entities.SaveChanges();
                                    OutputWriter.WriteLine("交易:" + dCache.Trade.tid + " 和相应的分销采购单的状态更新成功。", OutputFormatType.Success);
                                }
                                catch (Exception error)
                                {
                                    HandleException("交易:" + dCache.Trade.tid + " 和相应的分销采购单的状态更新异常。", error);
                                }
                                return;
                            }
                            #endregion
                             
                        }
                        catch (Exception te)
                        {
                        }

                        #region Need Delivery

                        DeliverySendRequest request = new DeliverySendRequest();
                        request.Tid = dCache.Trade.tid;
                        if (dCache.OrderType != Constants.OrderType_Virtual_Goods)
                        {
                            Model.Sender sender = (from s in Entities.Sender
                                                   where s.Shop == ShopID
                                                   select s).FirstOrDefault();
                            if (sender == null)
                            {
                                HandleException("采购单：" + dCache.Trade.tid + " 发货失败，没有当前店铺:" + ShopName + "的发送者信息！", new Exception("没有当前店铺:" + ShopID + "的发送者信息！"));
                                return;
                            }

                            if (String.IsNullOrEmpty(dCache.CompanyCode))
                            {
                                request.CompanyCode = sender.CompanyCode;
                            }
                            else
                            {
                                request.CompanyCode = dCache.CompanyCode;
                            }
                            request.Memo = String.IsNullOrEmpty(dCache.Memo) ? "Thanks," : dCache.Memo;
                            request.OutSid = dCache.OutSID;
                            request.SellerAddress = sender.Address;
                            request.SellerAreaId = sender.AreaID;
                            request.SellerMobile = sender.Mobile;
                            request.SellerName = sender.Name;
                            request.SellerPhone = sender.Phone;
                            request.SellerZip = sender.Zip; 

                        }
                        else
                        {
                            request.OrderType = dCache.OrderType;
                        }

                        Shipping shipping = Client.DeliverySend(request);
                        if (shipping.IsSuccess)
                        {
                            OutputWriter.WriteLine("采购单：" + " 发货成功。", OutputFormatType.Success);
                            dCache.Status = Constants.Delivery_Completed;
                            dCache.IsSucess = true;
                            succeedCount++;
                            Entities.SaveChanges();

                            //Update Trade && PurchaseOrder 
                            try
                            {
                                dCache.TradeReference.Load();
                                dCache.Trade.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;

                                List<Model.PurchaseOrder> purchaseOrders = (from o in Entities.PurchaseOrder
                                                                            where o.Trade.tid == dCache.Trade.tid
                                                                            && o.Shop.ShopId==ShopID
                                                                            select o).ToList();
                                purchaseOrders.ForEach(o =>
                                {
                                    o.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    o.SubPurchaseOrder.Load();
                                    foreach (Model.SubPurchaseOrder subOrder in o.SubPurchaseOrder)
                                    {
                                        subOrder.status = Constants.PurchaseOrder_WAIT_BUYER_CONFIRM_GOODS;
                                    }
                                });
                                Entities.SaveChanges();
                                OutputWriter.WriteLine("交易:" + dCache.Trade.tid + " 和相应的分销采购单的状态更新成功。", OutputFormatType.Success);
                            }
                            catch (Exception error)
                            {
                                HandleException("交易:" + dCache.Trade.tid + " 和相应的分销采购单的状态更新异常。", error);
                            }
                        }
                        else
                        {
                            OutputWriter.WriteLine("采购单：" + dCache.Trade.tid + " 发货失败。", OutputFormatType.Failed);
                            dCache.Shop = Shop;
                            dCache.Status = Constants.Delivery_Failed;
                            dCache.IsSucess = false;
                            Entities.SaveChanges();
                        }
                        #endregion

                    }
                    catch (Exception e)
                    {
                        try
                        {
                            if (dCache != null)//将所有发货未成功的订单状态都改为失败。
                            {
                                dCache.Shop = Shop;
                                dCache.Status = Constants.Delivery_Failed;
                                dCache.IsSucess = false;
                                Entities.SaveChanges();
                            }
                        }
                        catch { }
                        HandleException("采购单：" +d.Trade.tid + " 发货失败。", e);
                    }
                });
            }
            catch (Exception e)
            {
                HandleException("处理采购单发货异常终止！", e);
            }
            finally
            {
                LogstatisticsEnd("采购单发货", totalCount, succeedCount);
                DisposeEntities();
            }
        }
 
        /// <summary>
        /// Save the Refund to the DataBase, from the refund information of TAOBAO
        /// </summary>
        /// <param name="tRefund">the Refund information of TAOBAO</param>
        /// <returns></returns>
        protected bool SaveRefund(Refund tRefund)
        {
            try
            {
                Model.Refund dRefund =(from r in Entities.Refund
                                       where r.RefundID==tRefund.RefundId
                                       && r.Shop.ShopId ==ShopID
                                       select r).FirstOrDefault();
                bool addRecord = dRefund == null;
                if (addRecord )
                {
                    dRefund = new Model.Refund();
                    dRefund.RefundID = tRefund.RefundId;
                    dRefund.Shop = Shop;
                }                             

                dRefund.address = tRefund.Address;
                dRefund.alipay_no = tRefund.AlipayNo;
                dRefund.buyer_nick = tRefund.BuyerNick;
                dRefund.company_name = tRefund.CompanyName;
                if(!String.IsNullOrEmpty(tRefund.Created))
                    dRefund.created = Convert.ToDateTime(tRefund.Created);
                dRefund.desc = tRefund.Desc;
                if (!String.IsNullOrEmpty(tRefund.GoodReturnTime))
                    dRefund.good_return_time = Convert.ToDateTime(tRefund.GoodReturnTime);
                dRefund.good_status = tRefund.GoodStatus;
                dRefund.has_good_return = tRefund.HasGoodReturn;
                dRefund.iid = tRefund.Iid;
                if(!String.IsNullOrEmpty(tRefund.Modified))
                    dRefund.modified = Convert.ToDateTime(tRefund.Modified);
                dRefund.num = tRefund.Num;
                dRefund.num_iid = tRefund.NumIid;
                dRefund.order_status = tRefund.OrderStatus; ;
                dRefund.payment = tRefund.Payment;
                dRefund.price = tRefund.Price;
                dRefund.reason = tRefund.Reason;
                dRefund.refund_fee = tRefund.RefundFee;
                dRefund.seller_nick = tRefund.SellerNick;
                dRefund.shipping_type = tRefund.ShippingType;
                dRefund.sid = tRefund.Sid;
                dRefund.status = tRefund.Status;
                dRefund.title = tRefund.Title;
                dRefund.total_fee = tRefund.TotalFee;

                //Trade
                dRefund.tid = tRefund.Tid;                 

                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToRefund(dRefund);
                    Entities.SaveChanges();
                    message.AppendFormat("获得新的退款采购单:{0}.", tRefund.RefundId);
                }
                else
                {
                    Entities.SaveChanges(); 
                    message.AppendFormat("更新退款采购单:{0}.", tRefund.RefundId);
                }
                OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新退款单:"+tRefund.RefundId+"的信息到数据库失败！", e);
            }
            return false;
        }

        /// <summary>
        /// Save the purchase order to the Database, from the order information of TAOBAO
        /// </summary>
        /// <param name="tOrder">the order information from TAOBAO</param>
        /// <returns></returns>
        protected bool SavePurchaseOrder(PurchaseOrder tOrder, bool displayMessage)
        {
            try
            {
                Model.PurchaseOrder dOrder = (from o in Entities.PurchaseOrder
                                              where o.id == tOrder.ID
                                              && o.Shop.ShopId ==ShopID
                                              select o).FirstOrDefault();
                bool addRecord = dOrder == null;
                if (addRecord)
                {
                    dOrder = new Model.PurchaseOrder();
                    dOrder.id = tOrder.ID;
                }

                dOrder.alipay_no =(tOrder.AlipayNo);
                dOrder.buyer_nick = tOrder.BuyerNick;
                if (!String.IsNullOrEmpty(tOrder.ConSignTime))
                    dOrder.consign_time = Convert.ToDateTime(tOrder.ConSignTime);
                if (!String.IsNullOrEmpty(tOrder.Created))
                    dOrder.created = Convert.ToDateTime(tOrder.Created);
                dOrder.distributor_from = tOrder.DistributorFrom;
                dOrder.distributor_memo = tOrder.DistributorMemo;
                dOrder.distributor_payment = tOrder.DistributorPayment;
                dOrder.distributor_username = tOrder.DistributorUserName;
                //Set Distributor
                string nicks = tOrder.DistributorUserName;
                Model.Distributor distributor = (from d in Entities.Distributor
                                                 where d.distributor_name == tOrder.DistributorUserName
                                                 && d.Shop.ShopId ==ShopID
                                                 select d).FirstOrDefault();
                if (distributor != null)
                {
                    dOrder.Distributor = distributor;
                }
                else
                {
                    try
                    {
                        FenXiaoGetDistributorsRequest distrRequest = new FenXiaoGetDistributorsRequest();
                        distrRequest.Nicks = nicks;
                        PageList<Distributor> allDistributors = Client.FenXiaoGetDistributors(distrRequest);
                        if (allDistributors.Content.Count > 0)
                        {
                            Distributor td = allDistributors.Content[0];
                            dOrder.Distributor = new Model.Distributor();
                            dOrder.Distributor.alipay_account = td.AlipayAccount;
                            dOrder.Distributor.contact_person = td.ContactPerson;
                            dOrder.Distributor.created = ConvertDateTime(td.Created);
                            dOrder.Distributor.distributor_id = td.DistributorID;
                            dOrder.Distributor.distributor_name = td.DistributorName;
                            dOrder.Distributor.email = td.Email;
                            dOrder.Distributor.mobile_phone = td.MobilePhone;
                            dOrder.Distributor.phone = td.Phone;
                            dOrder.Distributor.Shop = Shop;
                            dOrder.Distributor.shop_web_link = td.ShopWebLink;
                            dOrder.Distributor.user_id = td.UserID;
                        }
                    }
                    catch (Exception ep)
                    { 
                    }
                }

                if (!String.IsNullOrEmpty(tOrder.Modified))
                    dOrder.modified = Convert.ToDateTime(tOrder.Modified);
                if (!String.IsNullOrEmpty(tOrder.PayTime))
                dOrder.pay_time =Convert.ToDateTime( tOrder.PayTime);
                dOrder.post_fee = tOrder.PostFee;
                dOrder.snapshot_url = tOrder.SnapShotUrl;
                dOrder.status = tOrder.Status;
                dOrder.supplier_from = tOrder.SupplierFrom;
                dOrder.supplier_username = tOrder.SupplierFrom;
                dOrder.total_fee = tOrder.TotalFee;
                dOrder.type = tOrder.Type;
                
                dOrder.Shop = Shop;

                dOrder.Trade = (from t in Entities.Trade
                                where t.tid == tOrder.ID
                                && t.Shop.ShopId ==ShopID
                                select t).FirstOrDefault();

                //Receiver 
                Model.Receiver receiver = (from r in Entities.Receiver
                                            where r.address == tOrder.Receiver.Address
                                                && r.city == tOrder.Receiver.City
                                                && r.district == tOrder.Receiver.District
                                                && r.mobile_phone == tOrder.Receiver.MobilePhone
                                                && r.name == tOrder.Receiver.Name
                                                && r.phone == tOrder.Receiver.Phone
                                                && r.state == tOrder.Receiver.State
                                                && r.zip == tOrder.Receiver.Zip
                                                && r.shop == ShopID
                                            select r).FirstOrDefault();
                if (receiver == null)
                {
                    receiver = new Model.Receiver();
                    receiver.address = tOrder.Receiver.Address;
                    receiver.city = tOrder.Receiver.City;
                    receiver.district = tOrder.Receiver.District;
                    receiver.mobile_phone = tOrder.Receiver.MobilePhone;
                    receiver.name = tOrder.Receiver.Name;
                    receiver.phone = tOrder.Receiver.Phone;
                    receiver.state = tOrder.Receiver.State;
                    receiver.zip = tOrder.Receiver.Zip;
                }
                dOrder.Receiver = receiver;
                                
                dOrder.SubPurchaseOrderCount = tOrder.SubPurchaseOrders.Count;

                //TODO: Distributor Information

                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToPurchaseOrder(dOrder);
                    Entities.SaveChanges();
                    message.AppendFormat("获得分销采购单:{0}成功", tOrder.ID);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新分销采购单:{0}成功", tOrder.ID);
                }
                if (displayMessage)
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新分销采购单:" + tOrder.ID + "的信息到数据库失败！", e,displayMessage);
            }
            return false;
        }

        /// <summary>
        /// Save the Sub Purchase Order to Database
        /// </summary>
        /// <param name="dOrder">The parent order in the Database, of the current suborder from TAOBAO</param>
        /// <param name="tSubOrder">The sub order from TAOBAO</param>
        /// <returns></returns>
        protected bool SaveSubPurchaseOrder(Model.PurchaseOrder dOrder, SubPurchaseOrder tSubOrder,bool displayMessage)
        {
            try
            {
                Model.SubPurchaseOrder dSubOrder = (from o in Entities.SubPurchaseOrder
                                                        where o.id == tSubOrder.ID
                                                        && o.Shop.ShopId ==ShopID
                                                        select o).FirstOrDefault();
                bool addRecord = dSubOrder == null;
                if (addRecord)
                {
                    dSubOrder = new Model.SubPurchaseOrder();
                    dSubOrder.id = tSubOrder.ID;
                }
                dSubOrder.buyer_payment = tSubOrder.BuyerPayment;
                if(!String.IsNullOrEmpty(tSubOrder.Created))
                    dSubOrder.created = Convert.ToDateTime(tSubOrder.Created);
                dSubOrder.distributor_payment = tSubOrder.DistributorPayment;
                    
                //Item TODO
                long pid = tSubOrder.ItemID; 

                Model.FenxiaoProduct mProduct = (from p in Entities.FenxiaoProduct
                                                 where p.pid == pid
                                                 && p.Shop.ShopId ==ShopID 
                                                 select p).FirstOrDefault();
                if (mProduct != null)
                {
                    dSubOrder.FenxiaoProduct = mProduct;
                }
                else
                {

                    try
                    {
                        FenXiaoGetProductsRequest pRequest = new FenXiaoGetProductsRequest();
                        pRequest.PID = pid.ToString();
                        PageList<FenxiaoProduct> products = Client.FenXiaoGetProducts(pRequest);
                        if (products.Content.Count > 0)
                        {
                            if (dSubOrder.FenxiaoProduct == null || dSubOrder.FenxiaoProduct.pid != pid)
                            {
                                dSubOrder.FenxiaoProduct = new Model.FenxiaoProduct();
                                dSubOrder.FenxiaoProduct.pid = pid;
                            }
                            FenxiaoProduct fp = products.Content[0];
                            dSubOrder.FenxiaoProduct.alarm_number = fp.AlertNumber;
                            dSubOrder.FenxiaoProduct.city = fp.City;
                            dSubOrder.FenxiaoProduct.cost_price = fp.CostPrice;
                            dSubOrder.FenxiaoProduct.created = ConvertDateTime(fp.Created);
                            dSubOrder.FenxiaoProduct.desc_path = fp.DescPath;
                            dSubOrder.FenxiaoProduct.have_guarantee = fp.HaveGuanrantee;
                            dSubOrder.FenxiaoProduct.have_invoice = fp.HaveInvoice;
                            dSubOrder.FenxiaoProduct.items_count = fp.ItemsCount;
                            dSubOrder.FenxiaoProduct.modified = ConvertDateTime(fp.Modified);
                            dSubOrder.FenxiaoProduct.name = fp.Name;
                            dSubOrder.FenxiaoProduct.orders_count = fp.OrdersCount;
                            dSubOrder.FenxiaoProduct.outer_id = fp.OuterID;
                            dSubOrder.FenxiaoProduct.pictures = fp.Pictures;
                            dSubOrder.FenxiaoProduct.postage_ems = fp.PostageEMS;
                            dSubOrder.FenxiaoProduct.postage_fast = fp.PostageFast;
                            dSubOrder.FenxiaoProduct.postage_id = fp.PostageID;
                            dSubOrder.FenxiaoProduct.postage_ordinary = fp.PostageOrdinary;
                            dSubOrder.FenxiaoProduct.postage_type = fp.PostageType;
                            dSubOrder.FenxiaoProduct.productcat_id = fp.ProductCatID;
                            dSubOrder.FenxiaoProduct.prov = fp.Province;
                            dSubOrder.FenxiaoProduct.quantity = fp.Quantity;
                            dSubOrder.FenxiaoProduct.retail_price_high = fp.RetailPriceHigh;
                            dSubOrder.FenxiaoProduct.retail_price_low = fp.RetailPriceLow;
                            dSubOrder.FenxiaoProduct.Shop = Shop;
                            dSubOrder.FenxiaoProduct.standard_price = fp.StandardPrice;
                            dSubOrder.FenxiaoProduct.status = fp.Status;
                        }
                    }
                    catch (Exception perror)
                    {
                    }
                }

                dSubOrder.item_outer_id = tSubOrder.ItemOuterID;

                dSubOrder.num = tSubOrder.Num;
                dSubOrder.price = tSubOrder.Price;
                dSubOrder.sku_id = tSubOrder.SkuID;
                dSubOrder.sku_outer_id = tSubOrder.SkuOuterID;
                dSubOrder.sku_properties = tSubOrder.SkuProperties;
                dSubOrder.snapshot_url = tSubOrder.SnapShotUrl;
                dSubOrder.status = tSubOrder.Status;
                dSubOrder.title = tSubOrder.Title;
                dSubOrder.total_fee = tSubOrder.TotalFee;

                dSubOrder.PurchaseOrder = dOrder;
                dSubOrder.Shop = Shop;

                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToSubPurchaseOrder(dSubOrder);
                    Entities.SaveChanges();
                    message.AppendFormat("获得新的分销采购单:{0}的子采购单:{1}.",dOrder.id, tSubOrder.ID);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新分销采购单:{0}的子采购单:{1}.", dOrder.id, tSubOrder.ID);
                }
                if (displayMessage)
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
                
                 
            }
            catch (Exception e)
            {
                HandleException("更新分销采购单:" + dOrder.id + "的子采购单:" + tSubOrder.ID + "到数据库失败！", e,displayMessage);
            }
            return false;
        }
        
        /// <summary>
        /// Save the Distributor's information to the Database
        /// </summary>
        /// <param name="tDistributor">The Distributor's information Get from TAOBAO</param>
        /// <returns></returns>
        protected bool SaveDistributor(Distributor tDistributor)
        {
            try
            {
                Model.Distributor dDistributor = (from d in Entities.Distributor
                                                  where d.distributor_id == tDistributor.DistributorID
                                                  && d.Shop.ShopId ==ShopID
                                                  select d).FirstOrDefault();
                bool addRecord = (dDistributor == null);
                if (addRecord)
                {
                    dDistributor = new Model.Distributor();
                    dDistributor.distributor_id = tDistributor.DistributorID;
                }
                dDistributor.alipay_account = tDistributor.AlipayAccount;
                dDistributor.contact_person = tDistributor.ContactPerson;
                //if (!String.IsNullOrEmpty(tDistributor.Created))
                //    dDistributor.created = Convert.ToDateTime(tDistributor.Created); 
                dDistributor.distributor_name = tDistributor.DistributorName;
                dDistributor.email = tDistributor.Email;
                //dDistributor.mobile_phone = tDistributor.MobilePhone;
                dDistributor.phone = tDistributor.Phone;
                dDistributor.shop_web_link = tDistributor.ShopWebLink;
                //dDistributor.user_id = tDistributor.UserID;
                dDistributor.Shop = Shop;

                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToDistributor(dDistributor);
                    Entities.SaveChanges();
                    message.AppendFormat("获得新的分销商信息:{0}.", tDistributor.DistributorID);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新分销商信息:{0}.", tDistributor.DistributorID);
                }
                OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新分销商信息:" + tDistributor.DistributorID + "的信息到数据库失败！", e);
            }
            return false;
        }
             

        protected bool SaveProductCat(ProductCat tProductCat)
        {
            try
            {
                var dProductCat = (from pc in Entities.ProductCat
                                   where pc.id == tProductCat.ID
                                   && pc.Shop.ShopId == ShopID
                                   select pc).FirstOrDefault();
                bool addRecord = dProductCat == null;
                if (addRecord)
                {
                    dProductCat = new Model.ProductCat();
                    dProductCat.id = tProductCat.ID;
                }
                dProductCat.Shop = Shop;
                dProductCat.product_num = tProductCat.ProductNum;
                dProductCat.name = tProductCat.Name;
                 
                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToProductCat(dProductCat);
                    Entities.SaveChanges();
                    message.AppendFormat("获得新的产品线:{0}.", tProductCat.ID);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新产品线:{0}.", tProductCat.ID);
                }
                OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新产品线:" + tProductCat.ID + "的信息到数据库失败！", e);
            }
            return false;
        }

        protected bool SaveFenXiaoProduct(FenxiaoProduct tProduct)
        {
            try
            {
                var dProduct = (from p in Entities.FenxiaoProduct
                                where p.pid == tProduct.PID
                                && p.Shop.ShopId == ShopID
                                select p
                                    ).FirstOrDefault();

                bool addRecord = dProduct == null;

                if (addRecord)
                {
                    dProduct = new Model.FenxiaoProduct();
                    dProduct.pid = tProduct.PID;
                }
                dProduct.Shop = Shop;
                dProduct.alarm_number = tProduct.AlertNumber;
                dProduct.city = tProduct.City;
                dProduct.cost_price = tProduct.CostPrice;
                if (!String.IsNullOrEmpty(tProduct.Created))
                    dProduct.created = Convert.ToDateTime(tProduct.Created);
                dProduct.desc_path = tProduct.DescPath;
                dProduct.have_guarantee = tProduct.HaveGuanrantee;
                dProduct.have_invoice = tProduct.HaveInvoice;
                dProduct.items_count = tProduct.ItemsCount;
                if (!String.IsNullOrEmpty(tProduct.Modified))
                    dProduct.created = Convert.ToDateTime(tProduct.Modified); 
                dProduct.name = tProduct.Name;
                dProduct.orders_count = tProduct.OrdersCount;
                dProduct.outer_id = tProduct.OuterID;
                dProduct.pictures = tProduct.Pictures;
                dProduct.postage_ems = tProduct.PostageEMS;
                dProduct.postage_fast = tProduct.PostageFast;
                dProduct.postage_id = tProduct.PostageID;
                dProduct.postage_ordinary = tProduct.PostageOrdinary;
                dProduct.postage_type = tProduct.PostageType;
                dProduct.productcat_id = tProduct.ProductCatID;
                dProduct.prov = tProduct.Province;
                dProduct.quantity = tProduct.Quantity;
                dProduct.retail_price_high = tProduct.RetailPriceHigh;
                dProduct.retail_price_low = tProduct.RetailPriceLow;
                dProduct.standard_price = tProduct.StandardPrice;
                dProduct.status = tProduct.Status;
               
                //Skus
                dProduct .FenXiaoProduct_Sku =new System.Data.Objects.DataClasses.EntityCollection<Model.FenXiaoProduct_Sku>();
                foreach (FenxiaoSku sku in tProduct.Skus)
                {
                    var dPSkuRelation = new Model.FenXiaoProduct_Sku();
                    dPSkuRelation.Shop = Shop;
                    dPSkuRelation.FenxiaoProduct = dProduct;
                    Model.FenxiaoSku dSku = (from s in Entities.FenxiaoSku
                                             where s.id == sku.ID
                                             && s.Shop.ShopId == ShopID
                                             select s).FirstOrDefault();
                    if (dSku == null)
                    {
                        dSku = new Model.FenxiaoSku();
                        dSku.id = sku.ID;
                    }
                    dSku.cost_price = sku.CostPrice;
                    dSku.name = sku.Name;
                    dSku.outer_id = sku.OuterID;
                    dSku.quantity = sku.Quantity;
                    dSku.Shop = Shop;
                    dPSkuRelation.FenxiaoSku = dSku;
                    dProduct.FenXiaoProduct_Sku.Add(dPSkuRelation);
                }

                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToFenxiaoProduct(dProduct);
                    Entities.SaveChanges();
                    message.AppendFormat("获得新的产品:{0}.", tProduct.PID);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新产品信息:{0}.", tProduct.PID);
                }
                OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新产品信息:" +  tProduct.PID + " 到数据库失败！", e);
            }
            return false;
        }
        
        protected bool SaveTrade(Trade tTrade ,bool displayMessage)
        {
            try
            {
                Model.Trade dTrade = (from t in Entities.Trade
                                      where t.tid == tTrade.Tid
                                      && t.Shop.ShopId == ShopID
                                      select t).FirstOrDefault();
                bool addRecord = dTrade == null;
                if (addRecord)
                {
                    dTrade = new Model.Trade();
                    dTrade.tid = tTrade.Tid;
                }
                dTrade.Shop = Shop;
                dTrade.adjust_fee = tTrade.AdjustFee;
                dTrade.alipay_no = tTrade.AlipayNo;
                dTrade.available_confirm_fee = tTrade.AvailableConfirmFee;
                dTrade.buyer_alipay_no = tTrade.BuyerAlipayNo;
                dTrade.buyer_email = tTrade.BuyerEmail;
                dTrade.buyer_flag = tTrade.BuyerFlag;
                dTrade.buyer_memo = tTrade.BuyerMemo;
                dTrade.buyer_message = tTrade.BuyerMessage;
                dTrade.buyer_nick = tTrade.BuyerNick;
                dTrade.buyer_obtain_point_fee = tTrade.BuyerObtainPointFee;
                dTrade.buyer_rate = tTrade.BuyerRate;
                dTrade.cod_fee = tTrade.CodFee;
                dTrade.cod_status = tTrade.CodStatus;
                dTrade.commission_fee = tTrade.CommissionFee; 
                dTrade.consign_time = ConvertDateTime(tTrade.ConsignTime);
                dTrade.created = ConvertDateTime(tTrade.Created);
                dTrade.discount_fee = tTrade.DiscountFee;
                dTrade.end_time = ConvertDateTime(tTrade.EndTime);
                dTrade.has_post_fee = tTrade.HasPostFee;
                dTrade.iid = tTrade.Iid;
                dTrade.invoice_name = tTrade.InvoiceName;
                dTrade.is_3D = tTrade.Is3D;
                dTrade.modified = ConvertDateTime(tTrade.Modified);
                dTrade.num = tTrade.Num;
                dTrade.num_iid = tTrade.NumIid;
                dTrade.payment = tTrade.Payment;
                dTrade.pay_time = ConvertDateTime(tTrade.PayTime);
                dTrade.pic_path = tTrade.PicPath;
                dTrade.point_fee = tTrade.PointFee;
                dTrade.post_fee = tTrade.PostFee;
                dTrade.price = tTrade.Price;
                dTrade.promotion = tTrade.Promotion;
                dTrade.real_point_fee = tTrade.RealPointFee;
                dTrade.received_payment = tTrade.ReceivedPayment;
                dTrade.receiver_address = tTrade.ReceiverAddress;
                dTrade.receiver_city = tTrade.ReceiverCity;
                dTrade.receiver_district = tTrade.ReceiverDistrict;
                dTrade.receiver_mobile = tTrade.ReceiverMobile;
                dTrade.receiver_name = tTrade.ReceiverName;
                dTrade.receiver_phone = tTrade.ReceiverPhone;
                dTrade.receiver_state = tTrade.ReceiverState;
                dTrade.receiver_zip = tTrade.ReceiverZip;
                dTrade.seller_alipay_no = tTrade.SellerAlipayNo;
                dTrade.seller_email = tTrade.SellerEmail;
                dTrade.seller_flag = tTrade.SellerFlag;
                dTrade.seller_memo = tTrade.SellerMemo;
                dTrade.seller_mobile = tTrade.SellerMobile;
                dTrade.seller_name = tTrade.SellerName;
                dTrade.seller_nick = tTrade.SellerNick;
                dTrade.seller_phone = tTrade.SellerPhone;
                dTrade.seller_rate = tTrade.SellerRate;
                dTrade.shipping_type = tTrade.ShippingType;
                dTrade.snapshot = tTrade.Snapshot;
                dTrade.snapshot_url = tTrade.SnapshotUrl;
                dTrade.status = tTrade.Status;
                dTrade.timeout_action_time = ConvertDateTime(tTrade.TimeoutActionTime);
                dTrade.title = tTrade.Title;
                dTrade.total_fee = tTrade.TotalFee;
                dTrade.trade_memo = tTrade.TradeMemo;
                dTrade.type = tTrade.Type; 
                dTrade.sid = tTrade.Sid;
                
                StringBuilder message = new StringBuilder();
                if (addRecord)
                {
                    Entities.AddToTrade(dTrade);
                    Entities.SaveChanges();
                    message.AppendFormat("获取新的交易信息：{0}",tTrade.Tid);
                }
                else
                {
                    Entities.SaveChanges();
                    message.AppendFormat("更新交易信息：{0}", tTrade.Tid);
                }
                if(displayMessage)
                    OutputWriter.WriteLine(message.ToString(), OutputFormatType.Success);
                return true;
            }
            catch (Exception e)
            {
                HandleException("更新分销交易:" + tTrade.Tid + "到数据库异常.", e,displayMessage);
            }
            return false;
        }

        protected bool SaveFullTrade(Trade tTrade)
        {
            if (SaveTrade(tTrade,true))
            {
                try
                {
                    TradeFullinfoGetRequest request = new TradeFullinfoGetRequest();
                    request.Tid = tTrade.Tid;
                    request.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                    Trade fullTTrade = Client.TradeFullinfoGet(request);
                    SaveTrade(fullTTrade,false);
                    OutputWriter.WriteLine("更新分销交易：" + tTrade.Tid + "的详细信息成功！", OutputFormatType.Success);
                    return true;
                }
                catch (Exception e)
                {
                    HandleException("更新分销交易："+tTrade.Tid+"的详细信息异常.",e);
                }
            }
            return false;
        }
          
        #endregion

        #region Assist Method

        protected int ProcessPageList<T>(string contentName, int pageSize, PageList<T> firstContentList,Func<int,PageList<T>> getNextContentList, Func<T,bool> processAction)
            where T : BaseObject
        {
            int success = 0;
            int pageCount = (int)(firstContentList.TotalResults / pageSize) + ((firstContentList.TotalResults % pageSize > 0) ? 1 : 0);
            OutputWriter.WriteLine("将要获取的" + contentName + "的总页数为:" + pageCount + "页，每页:" + pageSize + "条。", OutputFormatType.Title);
            int currentPageNo = 1;
            PageList<T> currentContentList = firstContentList;
            do
            {
                try
                {
                    OutputWriter.WriteLine("第" + currentPageNo + "页：", OutputFormatType.Title);
                    foreach (T t in currentContentList.Content)
                    {
                        if (processAction(t))
                            success++;
                    }
                }
                catch (Exception e)
                {
                    HandleException("更新第" + currentPageNo + "页的" + contentName + "失败。", e);
                    Thread.Sleep(1000);
                }
                currentPageNo++;
                currentContentList = getNextContentList(currentPageNo);
            } while (currentPageNo <= pageCount);
            return success;
        }

        #endregion

        #region Update Product Information From TAOBAO

        protected void UpdateProducts()
        {
            ExcuteUpdateStatus("正在更新产品信息");

            try
            {
                OutputWriter.WriteLine("开始更新产品信息...", OutputFormatType.Title);
                FenXiaoGetProductsRequest request = new FenXiaoGetProductsRequest();
                request.PageSize = ResourceManager.Current.OptionsConfig.pagesize;
                PageList<FenxiaoProduct> products = Client.FenXiaoGetProducts(request);
                OutputWriter.WriteLine("一共有：" + products.TotalResults + "条产品需要更新：", OutputFormatType.Title);

                ProcessPageList<FenxiaoProduct>("产品信息", request.PageSize.Value, products,
                    (pageNo) =>
                    {
                        request.PageNo = pageNo;
                        return Client.FenXiaoGetProducts(request);
                    },
                    SaveFenXiaoProduct);  
                 
            }
            catch (Exception e)
            {
                HandleException("更新产品信息异常",e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新产品信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        protected void UpdateProductCats()
        {
            ExcuteUpdateStatus("正在更新产品线信息");

            try
            {
                OutputWriter.WriteLine("开始更新产品线信息...", OutputFormatType.Title);
                FenXiaoGetProductCatsRequest request = new FenXiaoGetProductCatsRequest();
                request.Fields = "total_results,productcats";
                PageList<ProductCat> productCats = Client.FenXiaoGetProductCats(request);
                List<ProductCat> allProductCates = productCats.Content;

                OutputWriter.WriteLine("一共有：" + allProductCates.Count + "条产品线需要更新：", OutputFormatType.Title);

                foreach (ProductCat pcat in allProductCates)
                {                    
                    SaveProductCat(pcat);  
                }
            }
            catch (Exception e)
            {
                HandleException("更新产品线异常。", e);
            }
            finally
            {
                OutputWriter.WriteLine("结束更新产品线信息！", OutputFormatType.Title);
                OutputWriter.WriteLine("");
            }
        }

        #endregion

        #region Update PurchaseOrder and SubPurchaseOrder from the trade

        protected bool UpdateTradeInfoFromTAOBAO(Model.Trade mTrade)
        {
            if (mTrade == null)
                return false;
            try
            {
                TradeFullinfoGetRequest request = new TradeFullinfoGetRequest();
                request.Tid = mTrade.tid;
                request.Fields = "seller_nick, buyer_nick, title, type, created, sid, tid, seller_rate,buyer_flag, buyer_rate, status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, seller_memo, alipay_no, buyer_message, pic_path, iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, shipping_type, trade_memo, is_3D,orders";
                Trade fullTTrade = Client.TradeFullinfoGet(request);
                SaveTrade(fullTTrade, true);
            }
            catch (Exception te)
            {
                HandleException("从淘宝获取分销交易：" + mTrade.tid + " 的详细信息失败。", te, true);
            }

            PurchaseOrder tPOder = null;
            Model.PurchaseOrder mPOrder =null ;

            try
            {
                FenXiaoGetOrdersRequest request = new FenXiaoGetOrdersRequest();
                request.PurchaseOrderID = mTrade.tid;
                PageList<PurchaseOrder> purchaseOrders = Client.FenXiaoGetOrders(request);
                if (purchaseOrders.Content.Count > 0)
                {
                    tPOder = purchaseOrders.Content[0];
                    SavePurchaseOrder(tPOder, true);
                }
            }
            catch (Exception e)
            {
                HandleException("从淘宝获取分销采购单：" + mTrade.tid + " 的详细信息失败。", e, true);
                return false;
            }

            if (tPOder != null)
            {
                mPOrder = (from o in Entities.PurchaseOrder
                           where o.id == tPOder.ID && o.Shop.ShopId == ShopID
                          select o).FirstOrDefault();
                if (mPOrder != null)
                {
                    foreach (SubPurchaseOrder subPOrder in tPOder.SubPurchaseOrders)
                    { 
                        SaveSubPurchaseOrder(mPOrder, subPOrder, true); 
                    }

                    return true;
                }
            }

            return false;
        }

        protected void UpdateNotFinishedTradeInfosFromTAOBAO()
        {
            long total = 0, success = 0;
            string title = "未结束的分销采购单的详细信息";
            ExcuteUpdateStatus("正在更新本地未结束的分销采购单的详细信息...");
            try
            {
                InitializeEntities();
                OutputWriter.WriteLine("开始更新所有未结束的分销采购单的详细信息...", OutputFormatType.Title);
                List<Model.Trade> dTradeList = (from t in Entities.Trade
                                                where t.Shop.ShopId == ShopID
                                                && (t.status != Constants.PurchaseOrder_TRADE_CLOSED
                                                    || t.status != Constants.PurchaseOrder_TRADE_CLOSED_BY_TAOBAO
                                                    || t.status!= Constants.PurchaseOrder_TRADE_FINISHED)
                                                select t).ToList();

                LogstatisticsStart(title, total = dTradeList.Count);
                foreach (Model.Trade trade in dTradeList)
                {
                    if (UpdateTradeInfoFromTAOBAO(trade))
                        success++;
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                LogstatisticsEnd(title, total, success);
                DisposeEntities();
            }
        }
        #endregion
        
    }
}
